﻿/*   
    Copyright (C) 2009 Galaktika Corporation ZAO

    This file is a part of Galaktika.BusinessMonitor
 
    Galaktika.BusinessMonitor is a free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
      
    You should have received a copy of the GNU General Public License
    along with Galaktika.BusinessMonitor.  If not, see <http://www.gnu.org/licenses/>.
  
    If GPL v.3 is not suitable for your products or company,
    Galaktika Corp provides Galaktika.BusinessMonitor under a flexible commercial license
    designed to meet your specific usage and distribution requirements.
    If you have already obtained a commercial license from Galaktika Corp,
    you can use this file under those license terms.
*/

using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using Galaktika.BI.Runtime.Services;
using Galaktika.BI.Extensibility.Dom.Dac;

namespace Galaktika.BI.Silverlight.Controls
{
    using Galaktika.BI.DataManagement;

    public class SessionStateButton : SimpleButton
    {
        public SessionStateButton()
        {
            this.SessionStateAction = SessionStateAction.None;
            AnalysisTransactionManager.AfterCommandComplete += AnalysisServicesTransactionManager_AfterCommandComplete;
        }

        ~SessionStateButton()
        {
            AnalysisTransactionManager.AfterCommandComplete -= AnalysisServicesTransactionManager_AfterCommandComplete;
        }

        void AnalysisServicesTransactionManager_AfterCommandComplete(object sender, TransactionCommandResultEventArgs e)
        {
            if (e.ConnectionName == this.AConnectionName)
            {
                if (this.Dispatcher.CheckAccess())
                {
                    this.IsEnabled = AnalysisTransactionManager.GetHasPendingChanges(this.AConnectionName);// !e.Succeess;
                }
                else
                {
                    this.Dispatcher.BeginInvoke(() => this.IsEnabled = AnalysisTransactionManager.GetHasPendingChanges(this.AConnectionName));
                }
            }
        }

        public SessionStateAction SessionStateAction { get; set; }

        public string AConnectionName { get; set; }

        public bool AUseConfirmation { get; set; }

        public string AConfirmationText { get; set; }

        protected override void OnClick()
        {
            if (this.AUseConfirmation)
            {
                var exe = (IExecutionContext)this.Context.Services.GetService(typeof(IExecutionContext));
                var app = (IAppManager)this.Context.Services.GetService(typeof(IAppManager));
                if (exe != null && app != null)
                {
                    if (MessageBox.Show(
                            exe.Parse(this.Context, this.AConfirmationText),
                            app.GetAppTitle(),
                            MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
                    {
                        return;
                    }
                }
            }

            if (!string.IsNullOrEmpty(this.AConnectionName))
            {
                switch (this.SessionStateAction)
                {
                    case SessionStateAction.Commit:
                        // Выполняем commit транзакции на сервере (вызов веб сервиса)
                        // в фоновом потоке
                        this.ExecuteAction(
                            AnalysisTransactionManager.Commit,
                            Localization.Msg_CommitChanges,
                            () => string.Format(Localization.Msg_UnableToPerformTransactionAction,
                                              Localization.Str_Commit));
                        break;
                    case SessionStateAction.Rollback:
                        this.ExecuteAction(
                            AnalysisTransactionManager.Rollback,
                            Localization.Msg_RollbackChanges,
                            () => string.Format(Localization.Msg_UnableToPerformTransactionAction,
                                          Localization.Str_Rollback));
                        break;
                    default:
                        break;
                }
            }

            base.OnClick();
        }

        private void ExecuteAction(
            Func<IBindingContext, string, bool> action,
            string actionTitle,
            Func<string> getErrorMessage)
        {
            IExecutionContext exe = (IExecutionContext)this.Context.Services.GetService(typeof(IExecutionContext));
            if (exe != null)
            {
                // Получаем сервис управления фоновыми работами
                IUserTaskManager taskMgr = (IUserTaskManager)base.Context.Services.GetService(typeof(IUserTaskManager));
                if (taskMgr != null)
                {
                    taskMgr.RunTaskAsync(actionTitle,
                        state =>
                        {
                            try
                            {
                                if (action(this.Context, this.AConnectionName))
                                {
                                    exe.DoDrillDown(this.Context);
                                }
                            }
                            catch
                            {
                                taskMgr.Dispatcher.BeginInvoke(() =>
                                {
                                    IOutputService output = (IOutputService)base.Context.Services.GetService(typeof(IOutputService));
                                    if (output != null)
                                    {
                                        output.ShowWarning(
                                            getErrorMessage());
                                    }
                                });
                                throw;
                            }
                        });
                }
            }
        }

        public override void EndEdit()
        {
            base.AFont = null;
            base.IsEnabled = AnalysisTransactionManager.GetHasPendingChanges(this.AConnectionName);
            base.EndEdit();
        }
    }
}

namespace Galaktika.BI.DataManagement
{
    public enum SessionStateAction
    {
        Commit,
        Rollback,
        None
    }
}
